#include "snake.h"

#include <QDebug>

Snake::Snake(QRect w, int cl)
{
    wall = w;
    cellLenght = cl;
}

void Snake::born(QVector<QPoint> b)
{
    body = b;
    head = body[body.size()-1];
}

bool Snake::moveLeft()
{
    body.pop_front();
    head.setX( head.x() - (cellLenght+1) );
    body.append( head );
    return hasHeadCollision();
}

bool Snake::moveRight()
{
    body.pop_front();
    head.setX( head.x() + (cellLenght+1) );
    body.append( head );
    return hasHeadCollision();
}

bool Snake::moveUp()
{
    body.pop_front();
    head.setY( head.y() - (cellLenght+1) );
    body.append( head );
    return hasHeadCollision();
}

bool Snake::moveDown()
{
    body.pop_front();
    head.setY( head.y() + (cellLenght+1) );
    body.append( head );
    return hasHeadCollision();
}

QPoint Snake::getHead()
{
    return head;
}

void Snake::updateHead()
{
    head = body[body.size()-1];
}

QVector<QPoint>& Snake::getBody()
{
    return body;
}

bool Snake::growLeft()
{
    head.setX( head.x() - (cellLenght+1) );
    body.append( head );
    return hasHeadCollision();
}

bool Snake::growRight()
{
    head.setX( head.x() + (cellLenght+1) );
    body.append( head );
    return hasHeadCollision();
}

bool Snake::growUp()
{
    head.setY( head.y() - (cellLenght+1) );
    body.append( head );
    return hasHeadCollision();
}

bool Snake::growDown()
{
    head.setY( head.y() + (cellLenght+1) );
    body.append( head );
    return hasHeadCollision();
}

bool Snake::isValidEat(QPoint eat)
{
    for(int i=0; i<body.size(); i++){
        if( (eat - body[i]).manhattanLength() == 0 ){
            return false;
        }
    }
    return true;
}

bool Snake::hasHeadCollision()
{
    if( head.x() < 3 or head.x() > wall.width()-cellLenght or head.y() < 3 or head.y() > wall.height()-cellLenght ){
        qDebug() << "Collision with wall";
        return true;
    }
    for(int i=0; i<body.size()-1; i++){
        if( (head - body[i]).manhattanLength() == 0 ){
            qDebug() << "Collision with body";
            return true;
        }
    }
    return false;
}
